package com.igeek.boot.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.igeek.boot.constant.RedisConstant;
import com.igeek.boot.entity.User;
import com.igeek.boot.entity.UserRole;
import com.igeek.boot.mapper.UserMapper;
import com.igeek.boot.mapper.UserRoleMapper;
import com.igeek.boot.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.igeek.boot.utils.BCryptPasswordEncoderUtils;
import com.igeek.boot.utils.QiniuUtils;
import com.igeek.boot.utils.RedisUtils;
import com.igeek.boot.vo.PageQueryVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author jwj
 * @since 2023-12-26
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;
    //根据用户名查询用户详细信息
    @Transactional(readOnly = true)
    @Cacheable(cacheNames = "user",keyGenerator = "keyGenerator")
    @Override
    public User findUserByUsername(String username) {
        User user = baseMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));
        return user;
    }

    //个人信息图片上传

    @Override
    public String upload(MultipartFile imgFile) throws IOException {
        if(imgFile!=null){
            String oldName = imgFile.getOriginalFilename();
            if(StringUtils.hasLength(oldName)){
                //生成随机文件名
                String newName = UUID.randomUUID()+oldName.substring(oldName.lastIndexOf("."));
                //七牛云上传图片
                String img = QiniuUtils.uploadForQiniu(imgFile.getInputStream(), newName);
                return img;
            }
        }
        return null;
    }

    //个人中心 修改用户基本信息
    @Transactional
    @Override
    public boolean updateUserInfo(User user) {
        //判断是否修改了图片  --> 根据id查询  传过来图片名再修改
        User oldUser = baseMapper.selectById(user.getId());
        if(StringUtils.hasLength(user.getImg())){
            //1.如果密码有修改  就加密
            if(!user.getPassword().equals(oldUser.getPassword())){
                String newPwd = BCryptPasswordEncoderUtils.encodePassword(user.getPassword());
                user.setPassword(newPwd);
            }
            //如果数据库有图片  就删除redis的记录
            if(StringUtils.hasLength(oldUser.getImg())){
                redisTemplate.opsForSet().remove(RedisConstant.USER_DB_PIC,oldUser.getImg());
            }
            //如果没有就添加
            redisTemplate.opsForSet().add(RedisConstant.USER_DB_PIC,user.getImg());
        }
        //只针对非空字段进行更新
        int row = baseMapper.updateById(user);
        return row>0;
    }

    //多表分页查询
    @Transactional(readOnly = true)
    @Override
    public Page<User> findUserPage(PageQueryVO pageQueryVO) {
        Page<User> userPage = new Page<>(pageQueryVO.getCurrentPage(), pageQueryVO.getPageSize());

        String query = pageQueryVO.getQueryString();
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(StringUtils.hasLength(query) , User::getUsername , query);
        Page<User> page = userMapper.selectUserPage(userPage,lambdaQueryWrapper);
        //Page<User> page = baseMapper.selectPage(userPage, lambdaQueryWrapper);
        //Page<User> page =  userMapper.selectUserPage(userPage,pageQueryVO.getQueryString());
        return page;
    }

    //用户管理界面  添加用户信息
    @Transactional
    @Override
    public boolean addUserInfo(User user, Integer roleId) {
        //1.插入用户表的信息 --> 对用户的密码进行加密处理
        String newPwd = BCryptPasswordEncoderUtils.encodePassword(user.getPassword());
        user.setPassword(newPwd);
        int row1 = baseMapper.insert(user);
        //2.多表中插入用户&角色信息
        int row2 = userRoleMapper.insert(new UserRole(user.getId(), roleId));
        return row1 > 0 && row2 > 0;
    }

    //修改用户信息
    @Transactional
    @Override
    public boolean updateUser(User user, Integer roleId) {
        //1.修改用户的信息  --> 对密码进行加密处理
        //判断是否修改了图片  --> 根据id查询  传过来图片名再修改
        User oldUser = baseMapper.selectById(user.getId());
        if(StringUtils.hasLength(user.getImg())){
            //1.如果密码有修改  就加密
            if(!user.getPassword().equals(oldUser.getPassword())){
                String newPwd = BCryptPasswordEncoderUtils.encodePassword(user.getPassword());
                user.setPassword(newPwd);
            }
            //如果数据库有图片  就删除redis的记录
            if(StringUtils.hasLength(oldUser.getImg())){
                redisTemplate.opsForSet().remove(RedisConstant.USER_DB_PIC,oldUser.getImg());
            }
            //如果没有就添加
            redisTemplate.opsForSet().add(RedisConstant.USER_DB_PIC,user.getImg());
        }
        int row1 = baseMapper.updateById(user);
        //2.修改用户与角色的关系 --> 删除原有的多表关系 -->  根据userId进行修改
        int row2 = userRoleMapper.delete(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, user.getId()));
        int row3 = userRoleMapper.insert(new UserRole(user.getId(), roleId));
        return row1 > 0 && row2 > 0 && row3 > 0;
    }

    ////用户登录，封装token返回
    //@Override
    //public String login(LoginVO loginVO) {
    //    User users = new User();
    //    users.setUsername(loginVO.getUserName());
    //    users.setPassword(loginVO.getPassword());
    //    //进行查询当前用户是否存在
    //    User one = baseMapper.selectOne(new LambdaQueryWrapper<User>()
    //            .eq(User::getUsername, loginVO.getUserName())
    //            .eq(User::getPassword, loginVO.getPassword())
    //            );
    //    if (one!= null&&one.getUserId()==1) {
    //        //生成token
    //        String token = JwtHelper.createToken(one.getUserId(), one.getUsername());
    //        return token;
    //    }
    //    return null;
    //}
}
